package ro.ase.catalog.security.action;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.context.SecurityContextHolder;
import ro.ase.catalog.beans.*;
import ro.ase.catalog.beans.dto.AbsenceDTO;
import ro.ase.catalog.beans.dto.AverageDTO;
import ro.ase.catalog.beans.dto.GradeDTO;
import ro.ase.catalog.beans.dto.TeacherDisciplineStudentsDTO;
import ro.ase.catalog.security.dao.ISchoolClassDAO;
import ro.ase.catalog.security.service.*;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: Ioana
 * Date: 5/17/14
 * Time: 2:52 PM
 * To change this template use File | Settings | File Templates.
 */
@SuppressWarnings("serial")
public class TeacherAction extends ActionSupport {
        @Autowired
        IStudentService studentService;
        @Autowired
        ITeacherService teacherService;
        @Autowired
        ISchoolClassDAO schoolClassDAO;
        @Autowired
        IGradeService gradeService;
        @Autowired
        ITeacherDisciplineClassService teacherDisciplineClassService;
        @Autowired
        IAbsenceService absenceService;

        private Grade grade;
        private GradeDTO gradeDTO;
        private Absence absence;
        private AbsenceDTO absenceDTO;
        private  TeacherDisciplineStudentsDTO teacherDisciplineStudentsDTO;
        private Map<String, Object> teacherMap=new HashMap<String, Object>();
        private int totalCount;
        private String studentId;
        private String classId;
        private String teacherId;
        private String absenceState;
        private String gradeValue;
        private String isTeza;
        private InputStream inputStream;
        private String reportFile;

        public String totalAvg(){
            User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            Student student=studentService.getStudentByUserName(currentUser.getLoginname());
            List<AverageDTO> averageDTOs= studentService.getAverageByClasses(student.getSchoolClass());
         for(int i=0;i<averageDTOs.size();i++){
             if(averageDTOs.get(i).getDisplayName().equals(student.getLastName()+" "+student.getFirstName()))
             {
                 teacherMap.put("message", "Media pe primul semestru este: "+averageDTOs.get(i).getAvgSem1()+
                 " Media pe semestrul al 2 lea este: "+averageDTOs.get(i).getAvgSem2()+
                 " Iar media finala este "+averageDTOs.get(i).getTotalAvg());
                 i=averageDTOs.size()+1;
             }
         }
            teacherMap.put("succes" , true);
             return SUCCESS;
        }
        public String displayStudentsByClass()
        {
            List<TeacherDisciplineStudentsDTO> studentsDTOList;
            User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            Teacher teacher=teacherService.findByUserName(currentUser.getLoginname());
            SchoolClass schoolClass=schoolClassDAO.get(Integer.parseInt(classId));
            studentsDTOList=studentService.findAllStudentsByClass(teacher, schoolClass);
            totalCount=studentsDTOList.size();
            teacherMap.put("totalCount", totalCount);
            teacherMap.put("success", true);
            teacherMap.put("data", studentsDTOList);

            return SUCCESS;
        }

        public String averageByClasses(){

            List<AverageDTO> averageDTOs=new ArrayList<AverageDTO>();
            User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            Teacher teacher=teacherService.findByUserName(currentUser.getLoginname());
            averageDTOs=studentService.getAverageByClasses(teacher.getClassMaster());
            totalCount=averageDTOs.size();
            teacherMap.put("totalCount", totalCount);
            teacherMap.put("success", true);
            teacherMap.put("data", averageDTOs);

            return SUCCESS;
        }
    public String avgStudentExportXLS(){
        HSSFWorkbook myWorkBook = new HSSFWorkbook();
        HSSFSheet mySheet = myWorkBook.createSheet();
        try {
            Calendar calendar = Calendar.getInstance();
            User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            Teacher teacher=teacherService.findByUserName(currentUser.getLoginname());
            List<AverageDTO> averageByClasses = studentService.getAverageByClasses(teacher.getClassMaster());
            reportFile = "Raport studenti" + calendar.get(Calendar.YEAR)
                    + "".concat(".xls");

            Row headerRow = mySheet.createRow(0);
            headerRow.setHeightInPoints(50);
            Cell titleCell = headerRow.createCell(0);
            titleCell.setCellValue("Student Report "
                    + calendar.get(Calendar.YEAR) + "");

            setStudentAllInfo(mySheet, averageByClasses, "averageByClasses");

            try {
                ByteArrayOutputStream boas = new ByteArrayOutputStream();
                myWorkBook.write(boas);
                setInputStream(new ByteArrayInputStream(boas.toByteArray()));

            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }
    public String avgDisciplineExportXLS(){
        HSSFWorkbook myWorkBook = new HSSFWorkbook();
        HSSFSheet mySheet = myWorkBook.createSheet();
        try {
            Calendar calendar = Calendar.getInstance();
            List<AverageDTO> studentBeans = calculateAvgDiscipline();
            reportFile = "Raport discipline" + calendar.get(Calendar.YEAR)
                    + "".concat(".xls");

            Row headerRow = mySheet.createRow(0);
            headerRow.setHeightInPoints(50);
            Cell titleCell = headerRow.createCell(0);
            titleCell.setCellValue("Student Report "
                    + calendar.get(Calendar.YEAR) + "");

            setStudentAllInfo(mySheet, studentBeans, "averageByDiscipline");

            try {
                ByteArrayOutputStream boas = new ByteArrayOutputStream();
                myWorkBook.write(boas);
                setInputStream(new ByteArrayInputStream(boas.toByteArray()));

            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }
    private void setStudentAllInfo(HSSFSheet mySheet,
                                   List<AverageDTO> averageDTOList, String type) {
        int rowNum = 4;
        HSSFRow myRow = null;
        String[] columnHeadrer = new String[3];
        if  (type.equals("averageByDiscipline"))
          columnHeadrer   = new String[]{"Nume disciplina", "Medie semestrul 1", "Medie semestrul 2", "Medie finala"};
        if  (type.equals("averageByClasses"))
            columnHeadrer   = new String[]{"Nume intreg", "Medie semestrul 1", "Medie semestrul 2", "Medie finala"};
        try {
            Row header = mySheet.createRow(1);
            for (int i = 0; i < columnHeadrer.length; i++) {
                Cell monthCell = header.createCell(i);
                monthCell.setCellValue(columnHeadrer[i]);
            }
            for (AverageDTO studentBean : averageDTOList) {
                myRow = mySheet.createRow(rowNum++);
                myRow.createCell(0).setCellValue(studentBean.getDisplayName());
                myRow.createCell(1).setCellValue(studentBean.getAvgSem1().toString());
                myRow.createCell(2).setCellValue(studentBean.getAvgSem2().toString());
                myRow.createCell(3).setCellValue(studentBean.getTotalAvg().toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
        public String averageByDisciplines(){

            List<AverageDTO> averageDTOs = calculateAvgDiscipline();
            teacherMap.put("totalCount", totalCount);
            teacherMap.put("success", true);
            teacherMap.put("data", averageDTOs);
            return SUCCESS;
    }

    private List<AverageDTO> calculateAvgDiscipline() {

        List<TeacherDisciplineStudentsDTO> studentsDTOList=new ArrayList<TeacherDisciplineStudentsDTO>();
        List<AverageDTO> averageDTOs=new ArrayList<AverageDTO>();
        List<TeacherDisciplineClass>  teacherList=new ArrayList<TeacherDisciplineClass>();
        User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Student student=studentService.getStudentByUserName(currentUser.getLoginname());
        teacherList=teacherDisciplineClassService.getAllDisciplinesByStudent(student);
        for(int i=0;i<teacherList.size();i++)
        {
            TeacherDisciplineStudentsDTO studentsDTO=studentService.getAvgForStudentAtDiscipline(teacherList.get(i).getTeacher(), student);
            if(studentsDTO!=null)
            {
                     AverageDTO averageDTO= new AverageDTO();
                     averageDTO.setId(i);
                     averageDTO.setDisplayName(teacherList.get(i).getDiscipline().getName());
                     averageDTO.setAvgSem1(studentsDTO.getFirstSemAvg());
                     averageDTO.setAvgSem2(studentsDTO.getSecondSemAvg());
                     averageDTO.setTotalAvg(studentsDTO.getFinalAvg());
                     averageDTOs.add(averageDTO);
            }
        }
        return averageDTOs;
    }

    public String displayGradesByStudent() throws ParseException {
            List<GradeDTO> grades;
            User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            Teacher teacher=teacherService.findByUserName(currentUser.getLoginname());
            Student student=studentService.getStudentById(Integer.parseInt(studentId));
            if(gradeDTO==null)
                grades=gradeService.displayGradesByStudent(student, teacher);
            else
            {
                DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
                Date date=dateFormat.parse(gradeDTO.getDate());
                grades=gradeService.displayGradesByStudent(student,teacher, date);
            }
            totalCount=grades.size();
            teacherMap.put("totalCount", totalCount);
            teacherMap.put("success", true);
            teacherMap.put("data", grades);

            return SUCCESS;
        }

        public String displayGradesClassMasterView() throws ParseException {
            List<GradeDTO> grades;
            Teacher teacher=teacherService.getTeacherById(Integer.parseInt(teacherId));
            Student student=studentService.getStudentById(Integer.parseInt(studentId));
            if(gradeDTO==null)
            {
                grades=gradeService.displayGradesByStudent(student, teacher);
            }

            else
            {
                DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
                Date date=dateFormat.parse(gradeDTO.getDate());
                grades=gradeService.displayGradesByStudent(student, teacher, date);
            }
            totalCount=grades.size();
            teacherMap.put("totalCount", totalCount);
            teacherMap.put("success", true);
            teacherMap.put("data", grades);

            return SUCCESS;
        }

        public String addGrade()
        {
            if(isInteger(getGradeValue())){
            User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            Teacher teacher=teacherService.findByUserName(currentUser.getLoginname());
            Student student=studentService.getStudentById(Integer.parseInt(studentId));
            TeacherDisciplineClass teacherDisciplineClass=teacherDisciplineClassService.getByClassAndTeacher(teacher, student.getSchoolClass());
            grade.setStudent(student);
            grade.setTeacherDisciplineClass(teacherDisciplineClass);
            grade.setValue(BigDecimal.valueOf(Integer.valueOf(gradeValue)));
            if("on".equals(absenceState))
            grade.setTeza(true);
            gradeService.saveGrade(grade);
            teacherMap.put("success", true);
            teacherMap.put("message", "Nota salvata!");
            }else   {
                teacherMap.put("success", true);
                teacherMap.put("message", "Nota invalida!");
            }

            return SUCCESS;
        }

        public String displayAbsencesByStudent() throws ParseException {
            List<AbsenceDTO> absences;
            User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            Teacher teacher=teacherService.findByUserName(currentUser.getLoginname());
            Student student=studentService.getStudentById(Integer.parseInt(studentId));
            if(absenceDTO==null)
            absences=absenceService.displayAbsencesByStudent(student, teacher);
            else
            {
                DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
                Date date=dateFormat.parse(absenceDTO.getDate());
                absences=absenceService.displayAbsencesByStudent(student, teacher, date);
            }
            totalCount=absences.size();
            teacherMap.put("totalCount", totalCount);
            teacherMap.put("success", true);
            teacherMap.put("data", absences);

            return SUCCESS;
        }

        public String displayAbsencesClassMasterView() throws ParseException {
            List<AbsenceDTO> absences;
            Teacher teacher=teacherService.getTeacherById(Integer.parseInt(teacherId));
            Student student=studentService.getStudentById(Integer.parseInt(studentId));
            if(absenceDTO==null)
            {
                absences=absenceService.displayAbsencesByStudent(student, teacher);
            }

            else
            {
                DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
                Date date=dateFormat.parse(absenceDTO.getDate());
                absences=absenceService.displayAbsencesByStudent(student, teacher, date);
            }

            totalCount=absences.size();
            teacherMap.put("totalCount", totalCount);
            teacherMap.put("success", true);
            teacherMap.put("data", absences);

            return SUCCESS;
        }

        public String saveAbsence()
        {
            User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            Teacher teacher=teacherService.findByUserName(currentUser.getLoginname());
            Student student=studentService.getStudentById(Integer.parseInt(studentId));
            TeacherDisciplineClass teacherDisciplineClass=teacherDisciplineClassService.getByClassAndTeacher(teacher, student.getSchoolClass());
            absence.setStudent(student);
            absence.setTeacherDisciplineClass(teacherDisciplineClass);
            if(absenceState.equals("Motivata"))
                absence.setMotivata(true);
            absenceService.saveAbsence(absence);
            teacherMap.put("success", true);
            return SUCCESS;
        }

        public String modifyAbsence()
        {
            Absence absence1=absenceService.getAbsenceById(absence.getId()) ;
            absence1.setMotivata(true);
            absenceService.modifyAbsence(absence1);
            teacherMap.put("success", true);
            return SUCCESS;
        }

        public String displayAverages()
        {
           // totalCount=absences.size();
            teacherMap.put("totalCount", totalCount);
            teacherMap.put("success", true);
          //  teacherMap.put("data", absences);
            teacherMap.put("success", true);
            return SUCCESS;
        }

        public String displayPromotedStudents() throws ParseException {

            List<TeacherDisciplineStudentsDTO> aux;
            List<TeacherDisciplineStudentsDTO>  studentsDTOList=new ArrayList<TeacherDisciplineStudentsDTO>();
            List<TeacherDisciplineStudentsDTO>  searchStudents=new ArrayList<TeacherDisciplineStudentsDTO>();
            User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            Teacher teacher=teacherService.findByUserName(currentUser.getLoginname());
            SchoolClass schoolClass=schoolClassDAO.get(Integer.parseInt(classId));
            aux=studentService.findAllStudentsByClass(teacher, schoolClass);
            for(int i=0; i<aux.size();i++)
            {
                 if(aux.size()>0)
                 {
                     if(aux.get(i).getFinalAvg().doubleValue()>=5)
                     {
                         studentsDTOList.add(aux.get(i))  ;
                     }
                 }
            }

            if(teacherDisciplineStudentsDTO!=null && teacherDisciplineStudentsDTO.getLastName()!=null && teacherDisciplineStudentsDTO.getLastName()!="")
            {
                for(int i=0;i<studentsDTOList.size();i++)
                {
                    if(studentsDTOList.get(i).getLastName().equals(teacherDisciplineStudentsDTO.getLastName()))
                    {
                        searchStudents.add(studentsDTOList.get(i));
                    }
                }
            }
            if(searchStudents.size()>0)
                studentsDTOList=searchStudents;
            totalCount=studentsDTOList.size();
            teacherMap.put("totalCount", totalCount);
            teacherMap.put("success", true);
            teacherMap.put("data", studentsDTOList);

            return SUCCESS;
        }

    public String displayUnPromotedStudents() throws ParseException {

        List<TeacherDisciplineStudentsDTO> aux;
        List<TeacherDisciplineStudentsDTO>  studentsDTOList=new ArrayList<TeacherDisciplineStudentsDTO>();
        List<TeacherDisciplineStudentsDTO>  searchStudents=new ArrayList<TeacherDisciplineStudentsDTO>();
        User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Teacher teacher=teacherService.findByUserName(currentUser.getLoginname());
        SchoolClass schoolClass=schoolClassDAO.get(Integer.parseInt(classId));
        aux=studentService.findAllStudentsByClass(teacher, schoolClass);
        for(int i=0; i<aux.size();i++)
        {
            if(aux.size()>0)
            {
                if(aux.get(i).getFinalAvg().doubleValue()<5)
                {
                    studentsDTOList.add(aux.get(i))  ;
                }
            }
        }
        if(teacherDisciplineStudentsDTO!=null && teacherDisciplineStudentsDTO.getLastName()!=null && teacherDisciplineStudentsDTO.getLastName()!="")
        {
            for(int i=0;i<studentsDTOList.size();i++)
            {
                if(studentsDTOList.get(i).getLastName().equals(teacherDisciplineStudentsDTO.getLastName()))
                {
                          searchStudents.add(studentsDTOList.get(i));
                }
            }
        }
        if(searchStudents.size()>0)
            studentsDTOList=searchStudents;
        totalCount=studentsDTOList.size();
        teacherMap.put("totalCount", totalCount);
        teacherMap.put("success", true);
        teacherMap.put("data", studentsDTOList);

        return SUCCESS;
    }


    public IStudentService getStudentService() {
        return studentService;
    }

    public ITeacherService getTeacherService() {
        return teacherService;
    }

    public void setTeacherService(ITeacherService teacherService) {
        this.teacherService = teacherService;
    }

    public void setStudentService(IStudentService studentService) {
        this.studentService = studentService;
    }
    public boolean isInteger(String s) {
        Integer integer;
        try {
            integer=Integer.parseInt(s);
        } catch(NumberFormatException e) {
            return false;
        }
        if(integer>0&&integer<11)
        return true;
        else return false;
    }
    public String getGradeValue() {
        return gradeValue;
    }

    public void setGradeValue(String gradeValue) {
        this.gradeValue = gradeValue;
    }

    public Map<String, Object> getTeacherMap() {
        return teacherMap;
    }

    public void setTeacherMap(Map<String, Object> teacherMap) {
        this.teacherMap = teacherMap;
    }

    public InputStream getInputStream() {
        return inputStream;
    }

    public void setInputStream(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    public String getReportFile() {
        return reportFile;
    }

    public void setReportFile(String reportFile) {
        this.reportFile = reportFile;
    }

    public String getClassId() {
        return classId;
    }

    public void setClassId(String classId) {
        this.classId = classId;
    }

    public String getStudentId() {
        return studentId;
    }

    public void setStudentId(String studentId) {
        this.studentId = studentId;
    }

    public ISchoolClassDAO getSchoolClassDAO() {
        return schoolClassDAO;
    }

    public void setSchoolClassDAO(ISchoolClassDAO schoolClassDAO) {
        this.schoolClassDAO = schoolClassDAO;
    }

    public int getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }

    public IGradeService getGradeService() {
        return gradeService;
    }

    public void setGradeService(IGradeService gradeService) {
        this.gradeService = gradeService;
    }

    public Grade getGrade() {
        return grade;
    }

    public void setGrade(Grade grade) {
        this.grade = grade;
    }

    public ITeacherDisciplineClassService getTeacherDisciplineClassService() {
        return teacherDisciplineClassService;
    }

    public void setTeacherDisciplineClassService(ITeacherDisciplineClassService teacherDisciplineClassService) {
        this.teacherDisciplineClassService = teacherDisciplineClassService;
    }

    public IAbsenceService getAbsenceService() {
        return absenceService;
    }

    public void setAbsenceService(IAbsenceService absenceService) {
        this.absenceService = absenceService;
    }

    public Absence getAbsence() {
        return absence;
    }

    public void setAbsence(Absence absence) {
        this.absence = absence;
    }

    public String getAbsenceState() {
        return absenceState;
    }

    public void setAbsenceState(String absenceState) {
        this.absenceState = absenceState;
    }

    public String getTeacherId() {
        return teacherId;
    }

    public void setTeacherId(String teacherId) {
        this.teacherId = teacherId;
    }

    public String getTeza() {
        return isTeza;
    }

    public void setTeza(String teza) {
        isTeza = teza;
    }

    public GradeDTO getGradeDTO() {
        return gradeDTO;
    }

    public void setGradeDTO(GradeDTO gradeDTO) {
        this.gradeDTO = gradeDTO;
    }

    public AbsenceDTO getAbsenceDTO() {
        return absenceDTO;
    }

    public void setAbsenceDTO(AbsenceDTO absenceDTO) {
        this.absenceDTO = absenceDTO;
    }

    public TeacherDisciplineStudentsDTO getTeacherDisciplineStudentsDTO() {
        return teacherDisciplineStudentsDTO;
    }

    public void setTeacherDisciplineStudentsDTO(TeacherDisciplineStudentsDTO teacherDisciplineStudentsDTO) {
        this.teacherDisciplineStudentsDTO = teacherDisciplineStudentsDTO;
    }
}
